<?php
namespace Sdk\Message\Translator;

use Marmot\Interfaces\INull;
use Marmot\Interfaces\ITranslator;
use Sdk\Common\Translator\TranslatorTrait;

use Sdk\Message\Model\Message;
use Sdk\Message\Model\NullMessage;

use Sdk\Dictionary\Item\Translator\ItemTranslator;
use Sdk\User\Staff\Translator\StaffTranslator;
use Sdk\User\Member\Translator\MemberTranslator;

use Sdk\Dictionary\Item\Model\Item;
use Sdk\Dictionary\Item\Repository\ItemRepository;

/**
 * @todo
 * @SuppressWarnings(PHPMD.CyclomaticComplexity)
 * @SuppressWarnings(PHPMD.NPathComplexity)
 */
class MessageTranslator implements ITranslator
{
    use TranslatorTrait;

    protected function getItemTranslator() : ItemTranslator
    {
        return new ItemTranslator();
    }

    protected function getStaffTranslator() : StaffTranslator
    {
        return new StaffTranslator();
    }

    protected function getMemberTranslator() : MemberTranslator
    {
        return new MemberTranslator();
    }

    protected function getItemRepository() : ItemRepository
    {
        return new ItemRepository();
    }

    protected function fetchItem(int $id) : Item
    {
        return $this->getItemRepository()->scenario(ItemRepository::FETCH_ONE_MODEL_UN)->fetchOne($id);
    }

    protected function getNullObject() : INull
    {
        return NullMessage::getInstance();
    }

    public function arrayToObject(array $expression, $message = null)
    {
        if (empty($expression)) {
            return $this->getNullObject();
        }
        
        if ($message == null) {
            $message = new Message();
        }
        
        if (isset($expression['id'])) {
            $message->setId(marmot_decode($expression['id']));
        }
        if (isset($expression['title'])) {
            $message->setTitle($expression['title']);
        }
        if (isset($expression['content'])) {
            $message->setContent($expression['content']);
        }
        if (isset($expression['messageType'])) {
            $message->setMessageType($expression['messageType']);
        }
        if (isset($expression['messageScope'])) {
            $message->setMessageScope($expression['messageScope']);
        }
        if (isset($expression['receiver'])) {
            if ($expression['messageScope'] == Message::MESSAGE_SCOPE_IS_PERSON['MEMBER']) {
                $receiver = $this->getMembrTranslator()->arrayToObject($expression['receiver']);
            }
            if ($expression['messageScope'] == Message::MESSAGE_SCOPE_IS_PERSON['STAFF']) {
                $receiver = $this->getStaffTranslator()->arrayToObject($expression['receiver']);
            }
            $message->setReceiver($receiver);
        }
        if (isset($expression['publisher'])) {
            $publisher = $this->getStaffTranslator()->arrayToObject($expression['publisher']);
            $message->setPublisher($publisher);
        }
        if (isset($expression['status']['id'])) {
            $message->setStatus(marmot_decode($expression['status']['id']));
        }
        if (isset($expression['createTime'])) {
            $message->setCreateTime($expression['createTime']);
        }
        if (isset($expression['updateTime'])) {
            $message->setUpdateTime($expression['updateTime']);
        }

        return $message;
    }

    public function objectToArray($message, array $keys = array())
    {
        if (!$message instanceof Message) {
            return array();
        }
        
        if (empty($keys)) {
            $keys = array(
                'id',
                'title',
                'content',
                'messageType' => ['id', 'name'],
                'messageScope' => ['id', 'name'],
                'receiver' => ['id', 'name'],
                'expireTime',
                'publisher' => ['id', 'name'],
                'status',
                'createTime',
                'updateTime'
            );
        }

        $expression = array();

        if (in_array('id', $keys)) {
            $expression['id'] = marmot_encode($message->getId());
        }
        if (in_array('title', $keys)) {
            $expression['title'] = $message->getTitle();
        }
        if (in_array('content', $keys)) {
            $content = $message->getContent();
            $expression['content'] = $content;
            $expression['contentHerf'] = $this->contentFormatConversion($content);
        }
        if (isset($keys['messageType'])) {
            $expression['messageType'] = $this->getItemTranslator()->objectToArray(
                $this->fetchItem($message->getMessageType()),
                $keys['messageType']
            );
        }
        if (isset($keys['messageScope'])) {
            $expression['messageScope'] = $this->getItemTranslator()->objectToArray(
                $this->fetchItem($message->getMessageScope()),
                $keys['messageScope']
            );
        }
        if (isset($keys['receiver'])) {
            if ($message->getMessageScope() == Message::MESSAGE_SCOPE_IS_PERSON['MEMBER']) {
                $expression['receiver'] = $this->getMemberTranslator()->objectToArray(
                    $message->getReceiver(),
                    $keys['receiver']
                );
            }
            if ($message->getMessageScope() == Message::MESSAGE_SCOPE_IS_PERSON['STAFF']) {
                $expression['receiver'] = $this->getStaffTranslator()->objectToArray(
                    $message->getReceiver(),
                    $keys['receiver']
                );
            }
        }
        if (in_array('expireTime', $keys)) {
            $expireTime = $message->getExpireTime();
            $expression['expireTime'] = $expireTime;
            $expression['expireTimeFormatConvert'] = !empty($expireTime)
            ? $this->convertTimeZone('Y-m-d H:i', $expireTime)
            : '';
        }
        if (isset($keys['publisher'])) {
            $expression['publisher'] = $this->getStaffTranslator()->objectToArray(
                $message->getPublisher(),
                $keys['publisher']
            );
        }
        if (in_array('status', $keys)) {
            $expression['status'] = $this->statusFormatConversion(
                $message->getStatus(),
                Message::M_STATUS_TYPE,
                Message::M_STATUS_CN
            );
        }
        if (in_array('createTime', $keys)) {
            $createTime = $message->getCreateTime();
            $expression['createTime'] = $createTime;
            $expression['createTimeFormatConvert'] = !empty($createTime)
            ? $this->convertTimeZone('Y-m-d H:i', $createTime)
            : '';
        }
        if (in_array('updateTime', $keys)) {
            $updateTime = $message->getUpdateTime();
            $expression['updateTime'] = $updateTime;
            $expression['updateTimeFormatConvert'] = !empty($updateTime)
            ? $this->convertTimeZone('Y-m-d H:i', $updateTime)
            : '';
        }

        return $expression;
    }
        
    protected function contentFormatConversion(string $message) : array
    {
        $pattern = '/@herf:(.*?):(.*?)@/';
        
        if (preg_match($pattern, $message, $matches)) {
            return array(
                'herf' => $matches[0],
                'order' => $matches[1],
                'id' => marmot_encode($matches[2]),
            );
        }
        return $matches;
    }
}
